﻿using System.Collections.Generic;
using Bussiness.Exception;
using Bussiness.Model;
using Bussiness.Model.Type;
using Bussiness.Service.Base;
using Bussiness.Service.Factory;
using NHibernate;
using NHibernate.Criterion;

namespace Bussiness.Service.Impl {
    internal class NewServiceImpl : BaseService<New, long>, INewService {
        #region INewService Members

        public IList<New> Search(string keyWord, Language lang) {
            IList<New> list;
            try
            {
                ICriteria criteria = CreateCriteria();
                keyWord = keyWord.Trim();
                if (string.IsNullOrEmpty(keyWord))
                {
                    keyWord = "%" + keyWord + "%";
                    criteria.Add(Restrictions.Like("Title", keyWord))
                        .Add(Restrictions.Like("Description", keyWord))
                        .Add(Restrictions.Like("ContentHtml", keyWord))
                        .Add(Restrictions.Disjunction());
                }
                criteria.Add(Restrictions.Eq("Lang", lang));
                criteria.AddOrder(Order.Asc("Title"));
                list = criteria.List<New>();
            } catch (System.Exception ex)
            {
                throw new BussinessException("failure when search news", ex);
            }
            return list;
        }

        public IList<New> Search(string keyWord, Language lang, int start, int range, string orderProperty) {
            IList<New> list;
            try
            {
                ICriteria criteria = CreateCriteria();
                keyWord = keyWord.Trim();
                if (string.IsNullOrEmpty(keyWord))
                {
                    keyWord = "%" + keyWord + "%";
                    criteria.Add(Restrictions.Like("Title", keyWord))
                        .Add(Restrictions.Like("Description", keyWord))
                        .Add(Restrictions.Like("ContentHtml", keyWord))
                        .Add(Restrictions.Disjunction());
                }
                criteria.Add(Restrictions.Eq("Lang", lang));
                if (!string.IsNullOrEmpty(orderProperty)) criteria.AddOrder(Order.Asc(orderProperty));
                criteria.SetFirstResult(start).SetMaxResults(range);
                list = criteria.List<New>();
            } catch (System.Exception ex)
            {
                throw new BussinessException("failure when search news", ex);
            }
            return list;
        }

        public int CountByKeyWord(string keyWord, Language lang) {
            int count;
            try
            {
                ICriteria criteria = CreateCriteria();
                keyWord = keyWord.Trim();
                if (string.IsNullOrEmpty(keyWord))
                {
                    keyWord = "%" + keyWord + "%";
                    criteria.Add(Restrictions.Like("Title", keyWord))
                        .Add(Restrictions.Like("Description", keyWord))
                        .Add(Restrictions.Like("ContentHtml", keyWord))
                        .Add(Restrictions.Disjunction());
                }
                criteria.Add(Restrictions.Eq("Lang", lang)).SetProjection(Projections.RowCount());
                count = (int) criteria.UniqueResult();
            } catch (System.Exception ex)
            {
                throw new BussinessException("failure when search news", ex);
            }
            return count;
        }

        public IList<New> GetByCategory(long categoryId, Language lang) {
            Category category = CategoryServiceUtil.FindCategory(categoryId);
            return GetByCategory(category, lang);
        }

        public IList<New> GetByCategory(Category category, Language lang) {
            IList<New> list;
            try
            {
                ICriteria criteria = CreateCriteria();
                if (category != null)
                {
                    criteria.Add(Restrictions.Eq("Category", category));
                }
                criteria.Add(Restrictions.Eq("Lang", lang)).AddOrder(Order.Asc("Title"));
                list = criteria.List<New>();
            } catch (System.Exception ex)
            {
                throw new BussinessException("Failure when get news by category and language", ex);
            }
            return list;
        }

        public New GetFirstResult(long categoryId, Language lang) {
            IList<New> list = GetByCategory(categoryId, lang);
            if (list.Count > 0) return list[0];
            return null;
        }

        public IList<New> GetByCategory(Category category, Language lang, int start, int range, string orderProperty) {
            IList<New> list;
            ICriteria criteria = CreateCriteria();
            criteria.Add(Restrictions.Eq("Category", category))
                .Add(Restrictions.Eq("Lang", lang))
                .SetFirstResult(start)
                .SetMaxResults(range);
            if (!string.IsNullOrEmpty(orderProperty)) criteria.AddOrder(Order.Asc(orderProperty));
            try
            {
                list = criteria.List<New>();
            } catch (System.Exception ex)
            {
                throw new BussinessException("Fuilure when get new by category", ex);
            }
            return list;
        }

        public IList<New> GetByCategory(long categoryId, Language lang, int start, int range, string orderProperty) {
            try
            {
                Category category = CategoryServiceUtil.FindCategory(categoryId);
                return GetByCategory(category, lang, start, range, orderProperty);
            } catch (System.Exception ex)
            {
                throw new BussinessException("Fuilure when GetNewCategory", ex);
            }
        }

        public int CountByCategory(Category category, Language lang) {
            int count;
            try
            {
                ICriteria criteria = CreateCriteria();
                criteria.Add(Restrictions.Eq("Category", category))
                    .Add(Restrictions.Eq("Lang", lang))
                    .SetProjection(Projections.RowCount());
                count = (int) criteria.UniqueResult();
            } catch (System.Exception ex)
            {
                throw new BussinessException("Fuilure when count by category", ex);
            }
            return count;
        }

        public int CountByCategory(long categoryId, Language lang) {
            int count;
            try
            {
                Category category = CategoryServiceUtil.FindCategory(categoryId);
                count = CountByCategory(category, lang);
            } catch (System.Exception ex)
            {
                throw new BussinessException("Fuilure when count by category", ex);
            }

            return count;
        }

        public New GetFirstResult(Category category, Language lang) {
            IList<New> list = GetByCategory(category, lang);
            if (list.Count > 0)
            {
                return list[0];
            }
            return null;
        }

        #endregion
    }
}